package com.apes.scm.masterdata.party.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.cache.Cache;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.event.Listener;
import com.apes.framework.plugin.outbox.annotation.OutboxSubscriber;
import com.apes.hr.base.repository.WorkPostRepository;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.party.model.AccessProvider;
import com.apes.scm.masterdata.party.model.Corporate;
import com.apes.scm.masterdata.party.model.Party;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.*;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.*;

/**
 * 功能：公司信息
 *
 * @author xul
 * @create 2018-01-23 14:35
 */
@Service("companyService")
public class CompanyService extends DomainService {
    private static final String ROLE_TYPE = "Company";

    @Autowired
    PartyRepository partyRepository;

    @Autowired
    public PartyService partyService;

    @Autowired
    public PartyRoleService partyRoleService;

    @Autowired
    public PartyIdentificationRepository partyIdentificationRepository;

    @Autowired
    CompanyRepository companyRepository;

    @Autowired
    PartyRoleRepository partyRoleRepository;


    @Autowired
    CorporateSerive corporateSerive;
    @Autowired
    CorporateRepository corporateRepository;
    @Autowired
    AccessProviderRepository accessProviderRepository;
    @Autowired
    AccessProviderService accessProviderService;
    @Autowired
    SequenceService sequenceService;

    /*
     *  创建公司
     * */
    public Party save(SimpleRequest request) {

        // 获取模型
        Party party = request.getO(Party.class);

        // 设置当事人类型
        party.setPartyType("corporate");

        // 创建角色类型为  Company
        //获取流水号
        String sequenceCode = party.getCorporate().getOperation().getId().equals("001071") ? "PARTY_Company_Partner" :
                (party.getCorporate().getOperation().getId().equals("001072") ? "PARTY_Company_Direct_Store" : "PARTY_Company_Empower");
        party.setCompanyCode(sequenceService.getId(sequenceCode));
        party.addPartyRole(ROLE_TYPE, party.getCustomerCode(),party.getCorporate().isFin());

        // 设置注册省份、注册城市、办公省份、办公城市
        corporateSerive.setCorporateCityAndProvince(party);

        Party returnParty = partyService.saveAndFlush(party, ROLE_TYPE, party.getCompanyCode());

        // 重新把编码返给前端
        returnParty.setCompanyCode(party.getCompanyCode());

        return returnParty;

    }

    // 更新公司信息
    public Party update(SimpleRequest request) {
        // 获取模型
        Party party = request.getO(Party.class);

        party.setUpdateDate(new Date());
        PartyRole partyRole = party.getPatyRoleByType(ROLE_TYPE);
        partyRole.setFin(party.getCorporate().isFin());
        AccessProvider accessProvider = accessProviderRepository.findByCompany(partyRole.getId());
        if (accessProvider != null) {
            accessProvider.setLastUpdatedStamp(new Date());
            accessProviderRepository.saveAndFlush(accessProvider);
            // 重新更新注册省份、注册城市、办公省份、办公城市（由于目前前端只保存了注册区县，办公区县）
            corporateSerive.setCorporateCityAndProvince(party);
            if (party.isSettlementCenter()) {
                if (accessProvider.getCompanys().stream().filter(acc -> acc.getParty().isSettlementCenter()
                        && acc.getParty().getCorporate().getRegCity().getId().equals(party.getCorporate().getRegCity().getId())
                        && acc.getParty().getId() != party.getId()).count() > 0) {
                    throw new RuntimeException("同一接入商在同一城市只能有一个公司是【区域结算中心】");
                }
            }
            //刷新接入商
            accessProviderRepository.saveAndFlush(accessProvider);
        }

        Party returnParty = partyService.saveAndFlush(party, ROLE_TYPE, party.getCompanyCode());
        returnParty.setCompanyCode(party.getCompanyCode());
        // 更新相关信息
        return returnParty;
    }

    /**
     * 定义公司界面弹窗
     *
     * @param request
     */
    public Page<Party> findAll(SimpleRequest request) {
        Page<Party> partyPage = partyService.findPartyAllByTypeAndRole(request, "corporate", "Company");
        return partyPage;
    }


    /*
     * 查询公司 PartyRole 配合 findAll
     * */
    public String addCompanyRole(SimpleRequest simpleRequest) {
        return partyRoleService.addPartyTypeAndRoleId(simpleRequest, "corporate", "Company");
    }


    @Autowired
    EntityManager em;

    /*
     * 原生查询返回List<Map> 但key为大写，且不支持动态参数，不能返回 Page类型
     * */
    public Map find(SimpleRequest request) {
        Query query = em.createNativeQuery("SELECT id , name FROM MAS_PARTY A, MAS_PARTY_ROLE B WHERE A.ID = B.PARTY_ID AND B.ROLE_ID = 'Company'");
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map> list = query.getResultList();
        HashMap result = new HashMap();
        result.put("content", list);
        return result;
    }

    public Party findOne(long id) {
        return partyService.findOne(id);
    }

    /**
     * 根据SUCC查找公司信息
     *
     * @param request uscc 唯一标识码
     * @return
     */
    public Party findBySUCC(SimpleRequest request) {
        String uscc = request.get("uscc");
        return partyService.findPartyByIdTypeAndIdValueAndRoleId("PIT_USCC", uscc, "Company");
    }

    /**
     * 根据Code查找公司信息
     *
     * @param request code 公司编码
     * @return
     */
    public Party findByCode(SimpleRequest request) {

        return partyService.findPartyByIdTypeAndIdValue("CompanyCode", request.get("code"));
    }

    @Autowired
    private Cache cache;

    private static final String CONST_DEFAULT_CACHE_NAME = "companyCache";
    private static final String CONST_DEFAULT_CACHE_NAME_INIT_FLAG = "companyCacheInitFlag";

    /**
     * 查询所有公司
     *
     * @param request
     * @return
     */
    public JSONObject findAllCompany(SimpleRequest request) {
        String k = "company";

        Boolean init = (Boolean) cache.get(CONST_DEFAULT_CACHE_NAME, CONST_DEFAULT_CACHE_NAME_INIT_FLAG);
        if (init == null || !init) {
            JSONObject permitPurposeMap = new JSONObject();
            List<Map> company = new ArrayList<>();
            List<PartyRole> partyRoleList = partyRoleRepository.findAllCompany();
            partyRoleList.forEach(partyRole -> {
                Map result = new HashMap();
                Party party = partyRole.getParty();
                result.put("id", partyRole.getId());
                result.put("name", party.getName());
                Corporate corporate = corporateRepository.findByParty(party);
                if (corporate != null) {
                    result.put("operation", Optional.ofNullable(corporate.getOperation()).orElse(new Enumeration()).getDescription());
                } else {
                    result.put("operation", null);
                }
                company.add(result);
            });
            permitPurposeMap.put("pt_company", company);
            cache.put(CONST_DEFAULT_CACHE_NAME, k, permitPurposeMap);
            cache.put(CONST_DEFAULT_CACHE_NAME, CONST_DEFAULT_CACHE_NAME_INIT_FLAG, true);
        }
        return (JSONObject) cache.get(CONST_DEFAULT_CACHE_NAME, k);
    }

    @OutboxSubscriber(name = "清除公司缓存", aggregateType = "com.apes.scm.masterdata.party.model.PartyRole", condition = "role.id == 'Company'")
    public void clearCache(PartyRole partyRole) {
        String k = "company";
        cache.remove(CONST_DEFAULT_CACHE_NAME, k);
        cache.remove(CONST_DEFAULT_CACHE_NAME, CONST_DEFAULT_CACHE_NAME_INIT_FLAG);
    }

    public String getImage(SimpleRequest request) {
        Map m = request.getMap();
        Long companyId = m.containsKey("companyId") ? (Long) m.get("companyId") : request.getCompanyId();
        if (companyId == null) return null;
        Party company = partyService.findOne(companyId);
        if (company.getCorporate() == null || StringUtils.isEmpty(company.getCorporate().getLogo())) return null;
        //fileserver/view/5e730986735b1e02b0f6725a
        JSONArray images = JSON.parseArray(company.getCorporate().getLogo());
//        Object imageFile = images.stream().filter(image -> ((JSONObject) image).getString("fileName").startsWith((String) m.get("imageName"))).findFirst().orElse(null);
        Object imageFile = images.stream().filter(image -> {
            JSONObject imageObj = (JSONObject)image;
            if (imageObj.get("fileName") != null && imageObj.getString("fileName").startsWith((String) m.get("imageName"))) return true;
            return false;
        }).findFirst().orElse(null);
        if (imageFile == null) return null;
        return ((JSONObject) imageFile).getString("id");
    }


    /***
     * 通过Party获取PartyRole
     */
    @Listener(topic = "event:cm.company.findOne")
    public PartyRole findOne(SimpleRequest request) {
        return partyRoleRepository.findOne(
                JpaDsl.toCriteriaByEq(
                        "party.id", request.get("id"),
                        "role.id", "Company"
                )
        ).orElse(null);
    }

    public Page findByOperator(SimpleRequest request){
        JSONObject jo = request.getJO();
        JSONArray jsonArray = jo.getJSONObject("group").getJSONArray("filters");
        String id = "";
        String name = "";
        for (Object filter : jsonArray) {
            JSONObject filterJO = (JSONObject) filter;
            if (filterJO.getString("field").equals("id")) id = filterJO.getString("value");
            if (filterJO.getString("field").equals("name")) name = filterJO.getString("value");
        }
        // 查询公司权限
        List<String> companyIds = invoke("aut.post.findLocalRoleByPost", request.getPostId());
        if (companyIds == null || companyIds.isEmpty())
            return partyRoleRepository.findByOperator(id, name, PageRequest.of(request.get("page"), request.get("size")));
        return partyRoleRepository.findByOperatorAndCompanyIds(id, name, companyIds,PageRequest.of(request.get("page"), request.get("size")));
    }
}
